import frappe


def split_mr_by_default_supplier(doc, method):
    if (doc.material_request_type == 'Purchase' and 
        frappe.db.get_singles_value("Stock Settings", 'split_mr_by_default_supplier')
        and not doc.flags.split_mr):
        item_code_list = {item.item_code for item in doc.items}
        item_default_list = frappe.get_all('Item Default', 
                                        filters = {'company': doc.company,
                                                'parent': ('in', item_code_list)},
                                        fields=['default_supplier', 'parent'])
        supplier_item_map = {}
        first_mr_item_list = []
        for item_default in item_default_list:
            item_list = supplier_item_map.setdefault(item_default.default_supplier, set())
            item_list.add(item_default.parent)

        for i, (supplier, item_list) in enumerate(supplier_item_map.items()):
            if not i:
                first_supplier,first_mr_item_list = (supplier, item_list)
                doc.zelin_supplier = first_supplier                
            else:
                new_mr = frappe.copy_doc(doc, ignore_no_copy=False)
                new_mr.zelin_supplier = supplier
                new_mr.flags.split_mr = True
                new_mr.items = [row for row in doc.items if row.item_code in item_list]
                new_mr.insert()
                if doc.docstatus == 1: new_mr.submit()
        if first_mr_item_list:
            doc.items = [row for row in doc.items if row.item_code in first_mr_item_list]                

def split_se_by_po_item(doc, method):
    # 满足条件：移动类型为委外调拨，有关联采购订单，没有拆分物料移动自定义标记(避免拆分出来的单据重复执行这段代码)
    if (doc.purpose == "Send to Subcontractor" and doc.items
         and frappe.db.get_singles_value("Buying Settings", 'split_se_by_po_item')
         and (doc.purchase_order or doc.subcontracting_order) and not doc.flags.split_se):
        fg_items = {d.subcontracted_item for d in doc.items}    #获取不重复的委外成品物料清单
        if len(fg_items) > 1:                                   #仅在超过一个委外成品时执行代码  
            for i, fg_item in enumerate(fg_items):
                if not i:
                    first_fg_item = fg_item
                else:                                           #从第二个开始拆分(复制、保留原材料明细行)，新增insert单据
                    new_se = frappe.copy_doc(doc,ignore_no_copy=False)
                    new_se.supplier = doc.supplier              #以下两个字段被设置为不允许复制，这里通过代码复制
                    new_se.from_warehouse = doc.from_warehouse
                    new_se.to_warehouse = doc.to_warehouse
                    new_se.flags.split_se = True                #避免拆分出来的单据运行重复执行这段代码
                    new_se.items =[row for row in doc.items if row.subcontracted_item == fg_item]
                    new_se.insert(ignore_permissions = True)
            #第一个成品仅保留该委外成品所属的下层原材料        
            doc.items = [row for row in doc.items if row.subcontracted_item == first_fg_item]

def production_plan_delete_0_qty_subassembly(doc, method):
    if doc.sub_assembly_items:
        doc.sub_assembly_items = [row for row in doc.sub_assembly_items if row.qty]     #删除数量为0的行

def update_plan_reserved_stock_qty(doc, method):
    """生产计划保存有计划预留数量，由工单关联回生产计划并按合并与不合并两种模式
       更新销售订单明细计划预留数量
    """
    production_plan = doc.production_plan
    plan_item = doc.production_plan_item
    sales_order_item = doc.sales_order_item #reference_item是用合并后保留的最后一个sales_order_item关联的
    if sales_order_item and production_plan and plan_item:
        names = []
        item_refs = frappe.get_all("Production Plan Item Reference",
            filters= {"parent": production_plan, 'item_reference': sales_order_item},
            fields=['sales_order_item','plan_reserved_stock_qty']) 
        if item_refs:
            for item_ref in item_refs:
                if item_ref.plan_reserved_stock_qty:
                    if doc.docstatus == 1:
                        frappe.db.set_value('Sales Order Item', item_ref.sales_order_item, 
                                    'plan_reserved_stock_qty', item_ref.plan_reserved_stock_qty)
                    elif doc.docstatus == 2:
                        names.append(item_ref.sales_order_item)                    
        else:
            data = frappe.db.get_value('Production Plan Item', plan_item,['sales_order_item','plan_reserved_stock_qty'],as_dict=1)
            if data.plan_reserved_stock_qty:
                if doc.docstatus == 1:
                    frappe.db.set_value('Sales Order Item', data.sales_order_item, 
                                'plan_reserved_stock_qty', data.plan_reserved_stock_qty)
                elif doc.docstatus == 2:
                    names.append(data.get('sales_order_item'))
        if doc.docstatus == 2 and names:
            frappe.db.set_value('Sales Order Item', {'name':('in', names)},'plan_reserved_stock_qty', 0)